<template>
  <div class="bigBox">
    <div class="conteine">
      <el-row style="height: 100%;">
        <el-col :span="16" style="position: relative">
          <el-row class="right-wx">
            <el-col>{{ activePoson }}</el-col>
          </el-row>
          <el-row ref="leftContet" class="right-center">
            <el-row v-for="(msg, index) in msgArr" :key="index">
              <el-row class="time">
                <el-col><el-tag type="info" size="small">{{ timeEstimate(msg.createTime) }}</el-tag></el-col>
              </el-row>
              <el-row v-if="msg.type === 0" class="xtxx">
                <el-col>{{ msg.username + '  ' + msg.content }}</el-col>
              </el-row>
              <el-row v-else class="yhxx" style="position: relative" :data-height="getHeight(index)">
                <el-col v-if="msg.status === 1">
                  <el-col :ref="`bubbleFather${index}`" :span="21" style="position: relative; min-height: 50px;">
                    <span :ref="`bubble${index}`" class="txtMsg bubble" :style="{textAlign: msg.content.length > 25 ? 'left': 'center'}" v-html="msg.content" />
                  </el-col>
                  <el-col :span="3" style="text-align: center"><el-avatar :src="msg.avatar" /></el-col>
                </el-col>
                <el-col v-else>
                  <el-row style="position: relative">
                    <el-col :span="3" style="text-align: center"><el-avatar :src="msg.avatar" /></el-col>
                    <el-col :ref="`bubbleFather${index}`" :span="21" style="position: relative; min-height: 50px;">
                      <el-col class="heName textHiddn">{{ msg.name }}</el-col>
                      <el-col><span :ref="`bubble${index}`" class="sheTxtMsg bubbleLeft" :style="{textAlign: msg.content.length > 25 ? 'left': 'center'}" v-html="msg.content" /></el-col>
                    </el-col>
                  </el-row>
                </el-col>
              </el-row>
            </el-row>
          </el-row>
          <!--      消息提醒      -->
          <el-row v-show="newMsgShow" class="newMsg">
            <el-col :span="20" @click.native="scollHeigt">您有新的消息！</el-col>
            <el-col :span="4" class="Xcss" @click.native="newMsgShow = false">X</el-col>
          </el-row>
          <el-row class="right-footer">
            <el-row class="msgtop">
              <el-col :span="1">
                <el-tooltip class="item" effect="dark" content="表情包" placement="top">
                  <div>
                    <el-popover
                      ref="popover"
                      v-model="popoverFlag"
                      placement="top"
                      width="400"
                      trigger="click"
                    >
                      <div style="min-height: 485px">
                        <el-row class="memeListCss">
                          <div v-show="memeIsShow === 0">
                            <el-col v-for="(item, index) in memeArr.emotionList" :key="index" :span="3">
                              <div class="imgBox" @click="getImg(index)">
                                <img :title="item" :src="`https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/${index}.gif`">
                              </div>
                            </el-col>
                          </div>
                          <div v-show="memeIsShow === 1">
                            <el-col v-for="(item, index) in memeList" :key="index" :span="6">
                              <div class="meme-imgBox" @click="getmemeImg(item.memePath)">
                                <img :src="item.memePath">
                                <i v-show="isCloseX" class="el-icon-close closeX" @click="closeMeme(item._id)" />
                              </div>
                            </el-col>
                            <el-col :span="6" style="padding: 5px">
                              <btnFile @success="setImageUrl">
                                <div class="meme-imgBox addBox"><i class="el-icon-plus" /></div>
                              </btnFile>
                            </el-col>
                            <el-col :span="6" style="padding: 5px"><div class="meme-imgBox addBox"><i class="el-icon-minus" @click="isCloseX = !isCloseX" /></div></el-col>
                          </div>
                        </el-row>
                        <div class="meme-footer">
                          <el-row>
                            <el-col v-for="(item, index) in emoticonList" :key="index" :span="3" class="meme-footer-box" :class="{'meme-footer-active': index === memeIsShow}" @click.native="getMemeIndex(index)">
                              <i :class="item.ico" style="font-size: 25px; cursor: pointer" :title="item.title" />
                            </el-col>
                          </el-row>
                        </div>
                      </div>
                      <i slot="reference" class="el-icon-picture-outline-round meme" />
                    </el-popover>
                  </div>
                </el-tooltip>
              </el-col>
              <el-tooltip class="item" effect="dark" content="历史记录" placement="top">
                <el-col :span="1">
                  <el-popconfirm
                    confirm-button-text="好的"
                    cancel-button-text="不用了"
                    icon="el-icon-info"
                    icon-color="red"
                    title="是否要加载全部的聊天记录？"
                    @confirm="geHistoryMsg"
                  >
                    <el-col slot="reference" :span="1"><i class="el-icon-chat-line-round elicon" /></el-col>
                  </el-popconfirm>
                </el-col>
              </el-tooltip>
            </el-row>
            <!--       聊天框      -->
            <div ref="chatFrame" class="chat-frame" contenteditable="true" />
          </el-row>
          <el-button class="outButton" type="primary" size="small" plain @click="sendClick">发送</el-button>
        </el-col>
        <el-col :span="8" class="left-wx">
          <el-row class="right-title">成员列表({{ allUser.filter(t => t.status).length }}/{{ allUser.length }})</el-row>
          <el-row class="right-conten">
            <el-col v-for="(item, index) in lineUser" :key="index" class="peson">
              <el-col :span="4"><el-avatar :src="item.avatar" :style="{filter: `grayscale(${item.status === 1 ? 0 : 1})`}" /></el-col>
              <el-col :span="16" class="peson-middle textHiddn">
                <el-col>{{ item.name }}</el-col>
                <el-col style="font-size: 14px; color: #999">{{ item.synopsis || '他还没有签名哦~' }}</el-col>
              </el-col>
              <el-col v-if="item.status === 1" :span="4" class="tagCss"><el-tag type="success" size="small" effect="dark">在线</el-tag></el-col>
              <el-col v-else :span="4" class="tagCss"><el-tag type="info" size="small" effect="dark">离线</el-tag></el-col>
            </el-col>
          </el-row>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script>
import { FormatTime } from '@/utils/time'
import memeArr from '@/utils/meme'
import db from '@/utils/localstorage'
import btnFile from '../common/btnFile'
export default {
  name: 'Index',
  components: { btnFile },
  data() {
    return {
      user: db.get('USER'),
      // 监听是否出现向上滚动事件, 显示新消息提示
      flag: true,
      popoverFlag: false,
      isCloseX: false,
      memeIsShow: 0,
      memeArr,
      onlinePeson: [],
      newMsgShow: false,
      allUser: [],
      websocket: null,
      activePoson: '群聊大厅',
      msgArr: [],
      count: 0,
      emoticonList: [{ ico: 'el-icon-picture-outline-round', title: '表情' }, { ico: 'el-icon-star-off', title: '表情包' }],
      memeList: []
    }
  },
  computed: {
    lineUser() {
      return this.allUser.map(r => {
        if (this.onlinePeson.indexOf(r.username) !== -1) {
          this.$set(r, 'status', 1)
        } else {
          this.$set(r, 'status', 0)
        }
        return r
      }).sort((a, b) => a.status < b.status ? 1 : a.status > b.status ? -1 : 0)
    }
  },
  beforeDestroy() {
    console.log('断开连接')
    this.websocket.close()
    this.websocket = null
    this.flag = true
  },
  mounted() {
    //  初始化
    this.init()
    // 查询所有用户
    this.getUser()
    // 判断当前浏览器是否支持WebSocket
    if ('WebSocket' in window) {
      // eslint-disable-next-line no-undef
      this.websocket = new WebSocket(GLObconfig.socketURL + '?_id=' + this.user._id)
    } else {
      alert('当前浏览器 Not support websocket')
      this.$router.push('/')
    }
    this.websocket.onmessage = this.getMsg
    // 监听滚动事件
    window.onmousewheel = document.onmousewheel = (e) => {
      // 当滚动到底部是解除自动滚动限制
      if (e.wheelDelta < 0) {
        const ele = this.$refs.leftContet.$el
        if (ele.scrollTop + ele.clientHeight === ele.scrollHeight) {
          this.flag = true
        }
      } else if (e.wheelDelta > 0) {
        //  当监听到向上滚动时，限制自动滚动
        this.flag = false
      }
    }
  },
  methods: {
    init() {
      this.initInputDIV()
      this.getmemeList()
    },
    initInputDIV() {
      // 输入框自动获取焦点
      this.$nextTick(() => {
        var ele = this.$refs.chatFrame
        // 获取焦点
        ele.focus()
        ele.addEventListener('keydown', e => {
          // 本身有两种换行方式阻止enter换行后，可以直接用shift + enter 换行
          if (e.keyCode === 13 && !e.shiftKey) {
            // 发送消息
            this.sendClick()
            //  组织默认回车事件
            e.preventDefault()
          }
        })
      })
    },
    // 给内容添加表情
    getImg(index) {
      var ele = this.$refs.chatFrame
      ele.innerHTML += `<img src="https://res.wx.qq.com/mpres/htmledition/images/icon/emotion/${index}.gif" />`
      this.popoverFlag = false
      ele.focus()
      //  使获取焦点的元素光标移动至末尾
      this.setCursor(ele)
    },
    setCursor(ele) {
      if (typeof window.getSelection !== 'undefined' && typeof document.createRange !== 'undefined') {
        const range = document.createRange()
        range.selectNodeContents(ele)
        range.collapse(false)
        const sel = window.getSelection()
        sel.removeAllRanges()
        sel.addRange(range)
      } else if (typeof document.body.createTextRange !== 'undefined') {
        const textRange = document.body.createTextRange()
        textRange.moveToElementText(ele)
        textRange.collapse(false)
        textRange.select()
      }
    },
    getUser() {
      this.$get('/user/all').then(res => {
        const newData = res.data.data.record
        this.allUser = newData.map(t => {
          t.avatar = this.$baseURL + '/' + t.avatar
          return t
        })
      })
    },
    // 判断时间
    timeEstimate(val) {
      const time = val.split(' ')
      return FormatTime(new Date(), 'YYYY-MM-DD') === time[0] ? time[1] : time[0]
    },
    scollHeigt() {
      this.$nextTick(() => {
        const ele = this.$refs.leftContet.$el
        // 滚动到底部
        if (ele.scrollHeight > ele.clientHeight) {
          setTimeout(() => {
            // 设置滚动条到最底部
            ele.scrollTop = ele.scrollHeight
            ele.style.opacity = 1
            this.flag = true
            this.newMsgShow && (this.newMsgShow = false)
          }, 300)
        }
      })
    },
    // 发送信息
    sendClick() {
      var ele = this.$refs.chatFrame
      const params = {
        message: ele.innerHTML,
        sendFrom: this.user.username,
        name: this.user.name,
        avatar: this.user.avatar
      }
      const strParams = JSON.stringify(params)
      this.websocket.send(strParams)
      //  清空输入框
      ele.innerHTML = ''
      this.flag = true
    },
    // 处理数组
    getMsg(event) {
      const newData = JSON.parse(event.data)
      this.onlinePeson = newData.onLinePeson
      if (Array.isArray(newData.data)) {
        this.msgArr = newData.data.map(t => {
          this.$set(t, 'avatar', this.$baseURL + '/' + t.avatar)
          if (this.isName(t.username)) {
            this.$set(t, 'status', 1)
          }
          return t
        })
      } else {
        if (this.isName(newData.data.username)) {
          this.$set(newData.data, 'status', 1)
        }
        this.$set(newData.data, 'avatar', this.$baseURL + '/' + newData.data.avatar)
        this.msgArr.push(newData.data)
      }
      // 处理滚动条
      this.Setscoll()
    },
    // 判断名字是否一致
    isName(namea) {
      return namea === this.user.username
    },
    // 判断实际长度赋值给父元素，解决绝对定位引起的父元素高度不自适应问题
    getHeight(index) {
      this.$nextTick(() => {
        const num = this.$refs[`bubble${index}`][0].offsetHeight
        if (num !== 35) {
          this.$refs[`bubbleFather${index}`][0].$el.style.minHeight = num + 15 + 'px'
        }
      })
    },
    // 滚动事件
    Setscoll() {
      // 如果没有动过滚动条就让默认滚动到底部
      if (this.flag) {
        this.scollHeigt()
      } else {
        this.newMsgShow = true
      }
    },
    getMemeIndex(num) {
      this.memeIsShow = num
    },
    //  表情包
    getmemeList() {
      this.$get('/meme/list').then(res => {
        const newData = res.data.data
        this.memeList = newData.map(t => {
          t.memePath = this.$baseURL + '/' + t.memePath
          return t
        })
      })
    },
    // 发送标签包
    getmemeImg(url) {
      this.popoverFlag = false
      const msg = `<img src="${url}" style="width: 100px; height: 100px" />`
      const params = {
        message: msg,
        sendFrom: this.user.username,
        name: this.user.name,
        avatar: this.user.avatar
      }
      const strParams = JSON.stringify(params)
      this.websocket.send(strParams)
    },
    geHistoryMsg() {
      const loading = this.$loading({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      this.$get('/msg/all').then(res => {
        this.msgArr = []
        this.msgArr = res.data.data
      }).finally(() => {
        loading.close()
      })
    },
    // 获取文件上传地址
    setImageUrl(fileList) {
      if (fileList.length) {
        const data = fileList[0].response.data
        this.addMeme(`${data.filePath}/${data.fileName}`)
      }
    },
    // 增加表情包
    addMeme(url) {
      this.$post('/meme/add', { memePath: url }).then(res => {
        if (res.data.status === 1) {
          this.getmemeList()
        }
      })
    },
    closeMeme(id) {
      this.$delete('/meme/delete', { id: id }).then(res => {
        if (res.data.status === 1) {
          this.$message.success('删除成功')
          this.getmemeList()
        }
      })
    }
  }
}
</script>

<style scoped>
 .conteine {
     margin: 50px auto;
     background-color: #fff;
     width: 70%;
     height: 700px;
     border-radius: 25px;
     padding: 5px;
     box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)
 }
 .left-wx {
     position: relative;
     background-color: #fafafa;
     border-radius: 5px;
     height: 100%;
 }
 .right-conten {
   height: 608px;
   overflow: auto;
 }
 .right-wx {
     height: 55px;
     line-height: 50px;
     font-size: 18px;
     padding-left: 10px;
     border-bottom: 1px solid #cccccc;
 }
 .right-center {
   overflow: auto;
   overflow-x: hidden;
   height: 470px;
 }
 .right-center::-webkit-scrollbar {
   /*滚动条整体样式*/
   width : 10px; /*高宽分别对应横竖滚动条的尺寸*/
   height: 1px;
 }
 .right-center::-webkit-scrollbar-thumb {
   /*滚动条里面小方块*/
   border-radius: 10px;
   box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
   background : #cccccc;
 }
 .right-center::-webkit-scrollbar-track {
   /*滚动条里面轨道*/
   box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
   border-radius: 10px;
   background : #ededed;
 }
    .right-footer {
        height: 175px;
        border-top: 1px solid #ccc;
    }
  .right-title {
    height: 75px; text-align: center; line-height: 75px; font-size: 18px;
  }
  .peson {
    font-size: 16px;
    height: 68px;
    text-align: center;
    padding: 12px 0;
  }
  .peson-middle {
    text-align: left;
  }
  .tagCss {
    line-height: 44px;
  }
  .outButton {
    position: absolute;
    right: 1px;
    bottom: 8px;
  }
  .time {
    text-align: center;
    margin: 5px 0;
  }
  .xtxx {
    text-align: center;
    font-size: 14px;
    color: #cccccc;
  }
  .yhxx {
    padding: 5px 0;
  }
  .txtMsg {
    text-align: right; padding-right: 10px; line-height: 35px;
  }
  .bubble {
    position: absolute;
    line-height: 30px;
    right: 0;
    bottom: 10px;
    display: inline-block;
    padding: 2px 10px;
    min-width: 30px;
    max-width: 50%;
    min-height: 35px;
    border-radius: 5px;
    background-color: #95EC69;
    color: #000000;
    word-break: break-all;
    word-wrap: break-word;
    text-align: justify;
  }
 .bubble:after {
   content: '';
   position: absolute;
   clear: both;
   left: 100%;
   top: 10px;
   width: 16px;
   height: 16px;
   border-width: 0;
   border-style: solid;
   border-color: transparent;
   border-top-width: 10px;
   border-top-color: #95EC69;
   border-radius: 0 32px 0 0;
   color: #dddddd;
 }
 .sheTxtMsg {
   text-align: left; padding-left: 10px; line-height: 35px
 }
 .bubbleLeft {
   position: absolute;
   left: -5px;
   bottom: -5px;
   display: inline-block;
   padding: 2px 5px;
   min-width: 30px;
   max-width: 50%;
   min-height: 35px;
   border-radius: 5px;
   background-color: #E0E0E0;
   color: #000000;
   word-break: break-all;
   word-wrap: break-word;
   text-align: justify;
 }
 .bubbleLeft::after{
   content:'';
   position:absolute;
   right:100%;
   top:0px;
   width:16px;
   height:16px;
   border-width:0;
   border-style:solid;
   border-color:transparent;
   border-bottom-width:10px;
   border-bottom-color: #E0E0E0;
   border-radius:0 0 0 32px;color:#dddddd;
 }
 .heName {
   position: absolute;
   left: -23px;
   top: 0;
 }
  .newMsg {
    cursor: pointer;
    position: absolute;
    right: 11px;
    bottom: 175px;
    z-index: 99999;
    width: 120px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    background-color: #ffffff;
    color: #00ee00;
    border: 1px solid #cccccc;
  }
  .Xcss {
    text-align: center;
    border-left: 1px solid #cccccc;
  }
/* 表情包那行样式 */
  .msgtop {
    height: 35px;
    padding: 5px;
    text-align: center;
  }
   .meme {
    font-size: 25px;
    cursor: pointer;
     color: #2c2c2c;
  }
 .meme:hover {
   color: #499C54;
 }
  .elicon {
    font-size: 25px;
    color: #2c2c2c;
    cursor: pointer;
  }
 .elicon:hover {
   color: #499C54;
 }
  .memeListCss {
    text-align: center;
    height: 440px;
    overflow: auto;
  }
 .memeListCss::-webkit-scrollbar {
   display: none; /* Chrome Safari */
 }
  .meme-footer {
    width: 100%;
    height: 50px;
    position: absolute;
    background-color: #ffffff;
    bottom: 0;
    left: 0;
    box-shadow: 0 -2px 1px rgba(0, 0, 0, .10);
    text-align: center;
    padding: 5px;
  }
  .meme-footer-box {
    padding: 5px;
  }
  .meme-footer-active {
    background-color: #F4F5F5;
  }
  .imgBox {
    padding: 2px;
    cursor: pointer;
  }
 .imgBox:hover {
   background-color: #F4F5F5;
 }
 .imgBox:hover img {
   transform: scale(1.2);
 }
 .meme-imgBox {
   position: relative;
   cursor: pointer;
 }
 .meme-imgBox:hover {
   background-color: #F4F5F5;
 }
 .meme-imgBox img{
   width: 90%;
   height: 80px;
 }
 .chat-frame {
   width: 100%;
   height: 125px;
   overflow: auto;
   font-size: 16px;
   padding: 10px;
 }
 div[contenteditable] {
   outline: none;
 }
  .addBox {
    border: 1px dashed #3a8ee6;
  }
  .addBox i {
    font-size: 80px;
    color: #3a8ee6;
  }
  .closeX {
    position: absolute;
    top: 0;
    right: 0;
    color: red;
  }
</style>
